package com.dh.convert.node;

import java.lang.reflect.Field;
import java.util.EnumSet;
import java.util.Map;

import com.alibaba.fastjson.util.TypeUtils;
import com.dh.convert.jackson.JSON;
import com.dh.convert.mapping.BeanMappingObject;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.collect.Maps;

public class EnumNode extends AbstractNode {
	private EnumSet enumSet;
	private Map<Object, Object> enumMapping;
	private Class<?> srcCls;

	public TreeNode bulid(Field f) {
		super.bulid(f);
		this._isEnum = Boolean.TRUE;
		this.enumSet = EnumSet.allOf((Class<Enum>) currentClass);
		return this;
	}

	@Override
	public TreeNode getNode(String path) {
		return null;
	}

	public boolean checkNode(BeanMappingObject bmo) {
		boolean result = Boolean.FALSE;
		try {
			if (bmo.getTypeClass() != null) {
				return Boolean.TRUE;
			}
			bmo.setTypeClass(currentClass);
			if (currentClass.getName().equals(bmo.getType())) {
				return Boolean.TRUE;
			}
			String type = bmo.getType().trim();
			enumMapping = Maps.newHashMap();
			for (Object e : enumSet) {
				Class<?> enumClass = e.getClass();
				Field sf = enumClass.getDeclaredField(type);
				sf.setAccessible(true);
				srcCls = sf.getType();
				Object key = sf.get(e);
				enumMapping.put(key, e);
			}
			result = Boolean.TRUE;
		} catch (Exception e) {
			throw new IllegalArgumentException("enumNode check error " + bmo.toString(), e);
		}
		return result;
	}

	@Override
	public Object writeValue(JsonNode jn, BeanMappingObject bmo, Object value) {
		if (jn != null) {
			if (srcCls != null) {
				return enumMapping.get(JSON.treeToValue(jn, srcCls));
			}
			return JSON.treeToValue(jn, bmo.getTypeClass());
		}
		if (value != null) {
			if (srcCls != null) {
				return enumMapping.get(value);
			} else {
				Object e = TypeUtils.cast(value, currentClass, null);
				value = (e == null ? value : e);
			}
		}
		return value;
	}
}
